package it.valeandre.omino.adapter;

import it.valeandre.omino.InterFragmentInterface;
import it.valeandre.omino.MatchDetailsActivity;
import it.valeandre.omino.R;
import it.valeandre.omino.fragment.OminoPagerFragment;
import it.valeandre.omino.model.EventDetails;
import it.valeandre.omino.model.Match;
import it.valeandre.omino.model.Matches;
import it.valeandre.omino.model.Ranking;
import it.valeandre.omino.model.Result;
import it.valeandre.omino.model.Results;
import it.valeandre.omino.model.ScoreListItem;
import it.valeandre.omino.model.ScoreListItems;
import it.valeandre.omino.utils.ExpandAnimation;
import it.valeandre.omino.utils.ResBundle;
import it.valeandre.omino.utils.Utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.view.PagerAdapter;
import android.util.Pair;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.widget.AbsListView.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class OminoPagerAdapter extends PagerAdapter {

	public static final int TMP_RESULTS_PAGE = 0;
	public static final int RANKING_PAGE = 2;
	public static final int RESULTS_PAGE = 1;
	private SparseArray<View> mViewCache = new SparseArray<View>();
	private LayoutInflater mInflater;
	private ListView mList;
	private Context mContext;
	private TextView mEmptyView;
	private LinearLayout mGroup;
	private InterFragmentInterface mInterFragmentInterface;
	private int mCurrentPage = RESULTS_PAGE;
	private Handler mHandler = new Handler();
	private OminoPagerFragment mOminoPagerFragment;

	public OminoPagerAdapter(Context context, OminoPagerFragment ominoPagerFragment) {
		mInflater = LayoutInflater.from(context);
		mContext = context;
		mOminoPagerFragment = ominoPagerFragment;
		mInterFragmentInterface = (InterFragmentInterface) context;
	}

	@Override
	public int getCount() {
		return 3;
	}

	@Override
	public boolean isViewFromObject(View view, Object object) {
		return object.equals(view.getTag());
	}

	@Override
	public Object instantiateItem(ViewGroup container, int position) {
		mGroup = (LinearLayout) mInflater.inflate(R.layout.pager_item, null);
		mEmptyView = (TextView) mGroup.findViewById(R.id.pager_item_empty_view);
		mList = (ListView) mGroup.findViewById(R.id.pager_item_list);
		mList.setEmptyView(mEmptyView);
		mViewCache.put(position, mGroup);
		mGroup.setTag(position);
		switch (position) {
		case 0:
			fillTmpResults();
			break;
		case 1:
			fillResults();
			break;

		case 2:
			fillRanking();
			break;

		default:
			mGroup = null;
			break;
		}

		container.addView(mGroup);

		return position;
	}

	private void fillRanking() {
		LinearLayout group = (LinearLayout) mViewCache.get(2);
		if (group != null) {
			mEmptyView.setText(R.string.no_ranking);
			final RankingAdapter rankingAdapter = new RankingAdapter(mContext);
			mList = (ListView) group.findViewById(R.id.pager_item_list);
			mList.setAdapter(rankingAdapter);
			mList.setOnItemClickListener(new OnItemClickListener() {

				public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3) {
					View toolbar = view.findViewById(R.id.ranking_item_toolbar);
					final ImageView arrow = (ImageView) view.findViewById(R.id.ranking_team_arrow);
					final ExpandAnimation expandAni = new ExpandAnimation(toolbar, 300);
					expandAni.setAnimationListener(new AnimationListener() {

						public void onAnimationStart(Animation animation) {

						}

						public void onAnimationRepeat(Animation animation) {

						}

						public void onAnimationEnd(Animation animation) {
							if (expandAni.isExpanded()) {
								arrow.setImageResource(R.drawable.arrow_sans_up_32_white);
							} else {
								arrow.setImageResource(R.drawable.arrow_sans_down_32_white);
							}
						}
					});
					toolbar.startAnimation(expandAni);
				}
			});
			Ranking ranking = mInterFragmentInterface.getRanking();
			if (ranking != null) {
				rankingAdapter.setData(ranking);
			} else {
				// rankingAdapter.setData(new Ranking());
				loadRanking();
			}
		}

	}

	private void fillMatchDetails(LinearLayout container, EventDetails goalDetails) {
		for (Pair<String, String> pair : goalDetails.getEventDetailPairList()) {
			LinearLayout mScorersView = (LinearLayout) mInflater.inflate(R.layout.goal_detail_item, container, false);
			TextView minute = (TextView) mScorersView.findViewById(R.id.goal_detail_item_minute);
			TextView scorer = (TextView) mScorersView.findViewById(R.id.goal_detail_item_scorer);
			minute.setText(pair.first);
			scorer.setText(pair.second.replace("penalty", mContext.getResources().getString(R.string.penalty)));
			if (mScorersView.getLayoutParams() == null) {
				LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
				mScorersView.setLayoutParams(params);
			}
			container.addView(mScorersView);

		}

	}

	private void fillTmpResults() {
		LinearLayout group = (LinearLayout) mViewCache.get(0);
		if (group != null) {
			mEmptyView.setText(R.string.no_tmp_results);
			final ScoresAdapter resultsAdapter = new ScoresAdapter(mContext);
			mList = (ListView) group.findViewById(R.id.pager_item_list);
			mList.setAdapter(resultsAdapter);
			mList.setOnItemClickListener(new OnItemClickListener() {

				public void onItemClick(final AdapterView<?> adapter, View view, final int pos, long lpos) {
					View toolbar = view.findViewById(R.id.score_item_toolbar);
                    Button moreDetails = (Button) toolbar.findViewById(R.id.toolbar_more_details_button);
                    moreDetails.setOnClickListener(new OnClickListener() {

                        public void onClick(View v) {
                            Match match = (Match) adapter.getItemAtPosition(pos);
                            Intent detailIntent = new Intent(mContext, MatchDetailsActivity.class);
                            Bundle detailBundle = new Bundle();
                            detailBundle.putSerializable(ResBundle.KEY_BUNDLE_MATCH_DETAIL_DATA, match);
                            detailIntent.putExtra(ResBundle.KEY_INTENT_MATCH_DETAIL_DATA_BUNDLE, detailBundle);
                            mContext.startActivity(detailIntent);
                        }
                    });
                    final ImageView arrow = (ImageView) view.findViewById(R.id.score_match_arrow);
					if (toolbar.getTag() != null && !toolbar.getTag().equals("filled")) {
						fillMatchDetails((LinearLayout) toolbar.findViewById(R.id.score_toolbar_home_goals_container),
								((Match) adapter.getItemAtPosition(pos)).getHomeGoalDetailsPairList());
						fillMatchDetails((LinearLayout) toolbar.findViewById(R.id.score_toolbar_away_goals_container),
								((Match) adapter.getItemAtPosition(pos)).getAwayGoalDetailsPairList());
						toolbar.setTag("filled");
						LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) toolbar.getLayoutParams();
						params.height = android.widget.LinearLayout.LayoutParams.WRAP_CONTENT;
						toolbar.setLayoutParams(params);
					}
					final ExpandAnimation expandAni = new ExpandAnimation(toolbar, 200);
                    expandAni.setAnimationListener(new AnimationListener() {

                        public void onAnimationStart(Animation animation) {

                        }

                        public void onAnimationRepeat(Animation animation) {

                        }

                        public void onAnimationEnd(Animation animation) {
                            if (expandAni.isExpanded()) {
                                arrow.setImageResource(R.drawable.arrow_sans_up_32);
                            } else {
                                arrow.setImageResource(R.drawable.arrow_sans_down_32);
                            }
                        }
                    });
					toolbar.startAnimation(expandAni);
				}
			});
			Matches matches = mInterFragmentInterface.getTmpResults();
			if (matches != null /* && results.getResults().size() > 0 */) {
				// resultsAdapter.setData(results);
				ScoreListItems scoreListItems;
				try {
					scoreListItems = createResultList(matches);
				} catch (ParseException e) {
					scoreListItems = new ScoreListItems();
					e.printStackTrace();
				}
				resultsAdapter.setData(scoreListItems);
			} else {
				// resultsAdapter.setData(new Results());
				loadTmpResults();
			}
		}

	}

	private void fillResults() {
		LinearLayout group = (LinearLayout) mViewCache.get(1);
		if (group != null) {
			mEmptyView.setText(R.string.no_results);
			final ScoresAdapter resultsAdapter = new ScoresAdapter(mContext);
			mList = (ListView) group.findViewById(R.id.pager_item_list);
			mList.setAdapter(resultsAdapter);
			mList.setOnItemClickListener(new OnItemClickListener() {

				public void onItemClick(final AdapterView<?> adapter, View view, final int pos, long lpos) {
					View toolbar = view.findViewById(R.id.score_item_toolbar);
					Button moreDetails = (Button) toolbar.findViewById(R.id.toolbar_more_details_button);
					moreDetails.setOnClickListener(new OnClickListener() {
						
						public void onClick(View v) {
							Match match = (Match) adapter.getItemAtPosition(pos);
							Intent detailIntent = new Intent(mContext, MatchDetailsActivity.class);
							Bundle detailBundle = new Bundle();
							detailBundle.putSerializable(ResBundle.KEY_BUNDLE_MATCH_DETAIL_DATA, match);
							detailIntent.putExtra(ResBundle.KEY_INTENT_MATCH_DETAIL_DATA_BUNDLE, detailBundle);
							mContext.startActivity(detailIntent);
						}
					});
					final ImageView arrow = (ImageView) view.findViewById(R.id.score_match_arrow);
					if (toolbar.getTag() != null && !toolbar.getTag().equals("filled")) {
						fillMatchDetails((LinearLayout) toolbar.findViewById(R.id.score_toolbar_home_goals_container),
								((Match) adapter.getItemAtPosition(pos)).getHomeGoalDetailsPairList());
						fillMatchDetails((LinearLayout) toolbar.findViewById(R.id.score_toolbar_away_goals_container),
								((Match) adapter.getItemAtPosition(pos)).getAwayGoalDetailsPairList());
						toolbar.setTag("filled");
						LinearLayout.LayoutParams params = (android.widget.LinearLayout.LayoutParams) toolbar.getLayoutParams();
						params.height = android.widget.LinearLayout.LayoutParams.WRAP_CONTENT;
						toolbar.setLayoutParams(params);
					}
					final ExpandAnimation expandAni = new ExpandAnimation(toolbar, 200);
					expandAni.setAnimationListener(new AnimationListener() {

						public void onAnimationStart(Animation animation) {

						}

						public void onAnimationRepeat(Animation animation) {

						}

						public void onAnimationEnd(Animation animation) {
							if (expandAni.isExpanded()) {
								arrow.setImageResource(R.drawable.arrow_sans_up_32);
							} else {
								arrow.setImageResource(R.drawable.arrow_sans_down_32);
							}
						}
					});
					toolbar.startAnimation(expandAni);
				}
			});
			Matches matches = mInterFragmentInterface.getMatches();
			if (matches != null /* && results.getResults().size() > 0 */) {
				// resultsAdapter.setData(results);
				ScoreListItems scoreListItems;
				try {
					scoreListItems = createResultList(matches);
				} catch (ParseException e) {
					scoreListItems = new ScoreListItems();
					e.printStackTrace();
				}
				resultsAdapter.setData(scoreListItems);
			} else {
				// resultsAdapter.setData(new Results());
				loadResults();
			}
		}

	}

	private ScoreListItems createResultList(Matches matches) throws ParseException {
		boolean groupByDate = true;
		HashMap<Long, List<Match>> map = new HashMap<Long, List<Match>>();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		for (Match match : matches.getMatchList()) {
			long millisecDate;
			if (match.getDate() != null) {
				// millisecDate =
				// Utils.fromGMTStringDateToMillisec(Utils.formatOminoPagerDate(match.getDate()),
				// "EEE, dd MMM yyyy", Locale.UK);
				Utils.log("DATE = " + match.getDate());
				millisecDate = Utils.fromGMTStringDateToMillisec(Utils.formatOminoPagerDate(match.getDate()), dateFormat); // example:
																															// 2013-03-16T16:00:00+01:00
				Utils.log("DATE millisec = " + millisecDate);
			} else {
				groupByDate = false;
				millisecDate = -1;
			}

			List<Match> dateGroupedResults = map.get(millisecDate);
			if (dateGroupedResults == null) {
				dateGroupedResults = new ArrayList<Match>();
				map.put(millisecDate, dateGroupedResults);
			}
			dateGroupedResults.add(match);
		}

		ArrayList<ScoreListItem> scoreListItems = new ArrayList<ScoreListItem>();

		Set<Long> dates = map.keySet();
		List<Long> orderedDates;

		try {
			orderedDates = Utils.orderMillisecDates(dates);
		} catch (Exception e) {
			Utils.log("w", "dates sorting error occurred!");
			orderedDates = new ArrayList<Long>(dates);
			e.printStackTrace();
		}

		for (Long date : orderedDates) {
			if (groupByDate) {
				ScoreListItem header = new ScoreListItem();
				header.setHeader(true);
				String gmtDate = Utils.fromMillisecToStringGMT(date, "EEE, dd MMM yyyy", Locale.ITALIAN);
				header.setGmtDate(gmtDate);
				scoreListItems.add(header);
			}
			List<Match> group = map.get(date);
			// for(Result res: group) {
			// res.setHeader(false);
			// scoreListItems.add(res);
			// }
			for (int i = 0; i < group.size(); i++) {
				Match res = group.get(i);
				res.setHeader(false);
				if (i == group.size() - 1) {
					res.setLast(true);
				}
				scoreListItems.add(res);
			}
		}

		ScoreListItems items = new ScoreListItems();
		items.setScoreListItems(scoreListItems);
		return items;
	}

	private ScoreListItems createResultList(Results results) throws ParseException {
		boolean groupByDate = true;
		HashMap<Long, List<Result>> map = new HashMap<Long, List<Result>>();
		for (Result result : results.getResults()) {
			long millisecDate;
			if (result.getGmtDate() != null) {
				millisecDate = Utils.fromGMTStringDateToMillisec(Utils.formatOminoPagerDate(result.getGmtDate()), "EEE, dd MMM yyyy",
						Locale.UK);
			} else {
				groupByDate = false;
				millisecDate = -1;
			}

			List<Result> dateGroupedResults = map.get(millisecDate);
			if (dateGroupedResults == null) {
				dateGroupedResults = new ArrayList<Result>();
				map.put(millisecDate, dateGroupedResults);
			}
			dateGroupedResults.add(result);
		}

		ArrayList<ScoreListItem> scoreListItems = new ArrayList<ScoreListItem>();

		Set<Long> dates = map.keySet();
		List<Long> orderedDates;

		try {
			orderedDates = Utils.orderMillisecDates(dates);
		} catch (Exception e) {
			Utils.log("w", "Error sorting dates occurred!");
			orderedDates = new ArrayList<Long>(dates);
			e.printStackTrace();
		}

		for (Long date : orderedDates) {
			if (groupByDate) {
				ScoreListItem header = new ScoreListItem();
				header.setHeader(true);
				String gmtDate = Utils.fromMillisecToStringGMT(date, "EEE, dd MMM yyyy", Locale.ITALIAN);
				header.setGmtDate(gmtDate);
				scoreListItems.add(header);
			}
			List<Result> group = map.get(date);
			// for(Result res: group) {
			// res.setHeader(false);
			// scoreListItems.add(res);
			// }
			for (int i = 0; i < group.size(); i++) {
				Result res = group.get(i);
				res.setHeader(false);
				if (i == group.size() - 1) {
					res.setLast(true);
				}
				scoreListItems.add(res);
			}
		}

		ScoreListItems items = new ScoreListItems();
		items.setScoreListItems(scoreListItems);
		return items;
	}

	public void setCurrentPage(int currentPage) {
		mCurrentPage = currentPage;
	}

	public void refreshCurrentPage() {
		switch (mCurrentPage) {
		case RANKING_PAGE:
			loadRanking();
			break;

		case RESULTS_PAGE:
			loadResults();
			break;

		case TMP_RESULTS_PAGE:
			loadTmpResults();
			break;

		default:
			break;
		}
	}

	public void refreshAll() {
		loadRanking();
		loadResults();
		loadTmpResults();
	}

	private void loadResults() {
		mInterFragmentInterface.showProgress();
		mInterFragmentInterface.loadResults(false, new Observer() {

			public void update(Observable observable, final Object data) {
				Utils.log("i", "Results updated!");
				mHandler.post(new Runnable() {

					public void run() {
						if (data != null) {
							fillResults();
						}
						mInterFragmentInterface.hideProgress();

					}
				});

			}
		});
	}

	private void loadTmpResults() {
		mInterFragmentInterface.showProgress();
		mInterFragmentInterface.loadTmpMatches(false, new Observer() {

			public void update(Observable observable, final Object data) {
				Utils.log("i", "Tmp Results updated!");
				mHandler.post(new Runnable() {

					public void run() {
						if (data != null) {
							fillTmpResults();
						}
						mInterFragmentInterface.hideProgress();

					}
				});

			}
		});
	}

	private void loadRanking() {
		mInterFragmentInterface.showProgress();
		mInterFragmentInterface.loadRanking(false, new Observer() {

			public void update(Observable observable, final Object data) {
				Utils.log("i", "Ranking updated!");
				mHandler.post(new Runnable() {

					public void run() {
						if (data != null) {
							fillRanking();
							if (mOminoPagerFragment != null) {
								mOminoPagerFragment.updateDate(Utils.readRankingLastDate(mContext));
							}
						}
						mInterFragmentInterface.hideProgress();

					}
				});
			}
		});
	}

	@Override
	public void destroyItem(ViewGroup container, int position, Object object) {
		if (mViewCache.get(position) != null) {
			View view = mViewCache.get(position);
			container.removeView(view);
			mViewCache.remove(position);
		}
	}

}
